import re
from collections import defaultdict


class SearchEngine:
    def __init__(self, product_manager):
        self.product_manager = product_manager
        self.index = defaultdict(list)
        self._build_index()

    def _build_index(self):
        """构建倒排索引"""
        for product in self.product_manager.get_all_products():
            terms = self._tokenize(product)
            for term in set(terms):
                self.index[term].append(product.product_id)

    def _tokenize(self, product):
        """将产品信息分词"""
        text = f"{product.name} {product.description} {' '.join(product.tags)} {product.brand} {product.category}"
        return re.findall(r'\w+', text.lower())

    def search(self, query, sort_by="relevance", min_price=None, max_price=None, category=None, brand=None):
        """执行搜索并返回结果"""
        # 分词查询
        query_terms = re.findall(r'\w+', query.lower())

        # 查找匹配的产品ID
        matched_product_ids = set()
        for term in query_terms:
            if term in self.index:
                if not matched_product_ids:
                    matched_product_ids.update(self.index[term])
                else:
                    matched_product_ids.intersection_update(self.index[term])

        # 获取匹配的产品
        matched_products = [self.product_manager.get_product(pid) for pid in matched_product_ids]

        # 应用过滤条件
        if min_price is not None:
            matched_products = [p for p in matched_products if p.price >= min_price]
        if max_price is not None:
            matched_products = [p for p in matched_products if p.price <= max_price]
        if category is not None:
            matched_products = [p for p in matched_products if p.category == category]
        if brand is not None:
            matched_products = [p for p in matched_products if p.brand == brand]

        # 排序
        if sort_by == "price_asc":
            matched_products.sort(key=lambda x: x.price)
        elif sort_by == "price_desc":
            matched_products.sort(key=lambda x: x.price, reverse=True)
        elif sort_by == "rating":
            matched_products.sort(key=lambda x: x.rating, reverse=True)
        elif sort_by == "sales":
            matched_products.sort(key=lambda x: x.sales_volume, reverse=True)
        # 默认按相关性排序 (简单基于匹配词数量)
        elif sort_by == "relevance":
            def relevance_score(product):
                product_terms = self._tokenize(product)
                return sum(1 for term in query_terms if term in product_terms)

            matched_products.sort(key=relevance_score, reverse=True)

        return matched_products

    def get_suggestions(self, prefix, limit=5):
        """获取搜索建议"""
        prefix = prefix.lower()
        suggestions = []
        for term in self.index.keys():
            if term.startswith(prefix):
                suggestions.append(term)
                if len(suggestions) >= limit:
                    break
        return suggestions